auth模块的介绍


auth 模块一般用于用户注册、登录的认证、注销、修改密码等功能

注意: auth模块默认使用 auth_user表 来存储用户数据

auth模块的使用


1.导入auth模块

from django.contrib import auth

2. .authenticate() -> 用户认证

  • 用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数
  • 如果验证成功(用户名和密码正确有效)会返回一个User对象,且该User对象下会包含所有auth_user表的所有字段属性
  • 如果验证失效(用户名和密码错误无效)会返回一个匿名用户对象,即: None

from django.contrib import auth

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = auth.authenticate(username=username, password=password)  # 对用户进行验证,且返回一个User对象

# User对象下会包含auth_user表的所有字段属性
        print(user.username)  # Kevin
        print(user.password)  # 密文密码: pbkdf2_sha256$36……

    return render(request, 'login.html')

3. .login(request, user) -> 将user对象封装到request对象里面

  • .login() 方法接受两个参数:
    • request对象
    • 经过认证后所返回的User对象

  • .login() 的作用:
    • 将user对象封装到request对象里面,且所有的视图函数可以通过 request.user 获取user对象里面的相关属性
    • 实现了一个用户登录功能,它的本质会在后端为该用户生成相关session数据(类似于x天免登陆功能一样)

  • 注意: 

    • 只要执行了 .login(request, user) 之后,那么所有的所有的视图函数都能通过 request.user 拿到当前登录用户的相关信息(即: auth_user表里面的相关字段的数据)

    • 当 .authenticate() 认证用户失败的时候会返回一个匿名用户对象(即: None),通过 .login() 匿名用户对象封装到request对象里面后,在视图函数中使用 request.user 拿到的不是一个 None ,而是一个对象,里面存放着user表的所有字段属性,但是数据都是为空的(即: {username:'', password:'', ……}),所以 .authenticate() 的返回值 和 封装到 request 里面后再通过 request.user 取到的值是有区别的

from django.shortcuts import render, HttpResponse, redirect
from django.contrib import auth


def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = auth.authenticate(username=username, password=password)  # 对用户进行验证,且返回一个User对象

        if user:  # 判断user对象是否有效
            auth.login(request, user)  # 将user对象封装到request对象里面
            return redirect('/index/')

    return render(request, 'login.html')


def index(request):
 # 通过 request.user 获取当前登录用户的相关信息(即: auth_user表里面的相关字段的数据)
    print(request.user.username)  # Kevin
    print(request.user.password)  # 密文密码: pbkdf2_sha256$36……
    print(request.user.email)  # 123@qq.com
    return HttpResponse('index.html')

4. .logout(request) -> 注销

  • .logout() 方法接受一个request对象,且该方法没有返回值

  • .logout() 作用: 
    • 注销
    • 当调用.logout()方法时,当前请求的session信息会全部清除(即: 执行了 request.session.flush() 
    • 用户即使没有登录,使用.logout()方法也不会报错

from django.contrib import auth

def logout_view(request):
    auth.logout(request)  # 注销,相当于执行了 request.session.flush()
    return redirect('/login/')

5. .is_authenticated() -> 判断当前用户是否通过了认证

  • 返回值:

    • True -> 返回一个验证通过的user对象,即为True
    • False -> 返回一个匿名用户对象,即为False

from django.contrib import auth

def my_view(request):
    if not request.user.is_authenticated():
        return HttpResponse('该用户没有通过认证')

6.login_requierd 装饰器

  • 作用: 给某个视图函数添加login_requierd装饰器,只有用户登录了才能执行该视图函数

  • 导入login_requierd装饰器

from django.contrib.auth.decorators import login_required

  • 修改Django默认跳转的登录URL

    • 若用户没有登录,则会跳转到django默认的,登录URL '/accounts/login/',所以需要修改默认跳转的登录URL
    • 当用户没有登录,会将当前的url路径(不包括域名)传递给登录URL作为参数拼接起来,即 /login/?next=/my_view/

# settings.py

LOGIN_URL = '/login/'

  • 使用login_requierd装饰器

from django.contrib import auth
from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    return HttpResponse('my_view')

用户的相关操作


注意: 

  • 用户的相关操作和ORM的操作类似,都需要操作表的类或表的类所返回的对象

  • ModelForm 组件 和 auth 模块搭配使用的时候,不要使用 ModelForm 中的 .save(),因为在创建用户的时候 moelform 不是使用 create_user 创建的

1. 导入User类

  • 注意: 这个User类和我们平时在models.py所写的类是一样的,只不过User类是Django帮我们生成的

from django.contrib.auth.models import User

2..create_user() -> 创建普通用户

  • 注意: 不要使用 .create() 方法去添加,因为使用 .create() 方法所添加的密码是不会进行加密的

from django.contrib.auth.models import User

def my_view(request):

    user = User.objects.create_user(username='Yeung', password='123', email='123@qq.com')  # 添加普通用户

    return HttpResponse('添加成功')

3. .create_superuser() -> 创建超级用户

  • 注意: 不要使用 .create() 方法去添加,因为使用 .create() 方法所添加的密码是不会进行加密的

from django.contrib.auth.models import User

def my_view(request):

    user = User.objects.create_superuser(username='Aimer', password='123', email='123@qq.com')  # 添加超级用户

    return HttpResponse('添加成功')

  • 使用命令行添加超级用户

    • 密码必须是英文和数字组成的8位密码

python manage.py createsuperuser

4. avatar 字段的相关说明

  • 当需要往 avatar 字段添加数据的时候,avatar 字段必须接收一个文件对象,因为avatar字段一般是由 FileField 字段类 或 ImageField 字段类所创建的 (详细请查看: ORM-操作数据/添加数据/FileField 或 ImageField 字段类)

def register(request):
    if request.method == 'POST':
        file_obj = request.FILES.get('avatar')  # 接受一个文件对象
        if file_obj:  # 判断是否是一个文件对象
            # avatar 字段是通过 FileField 或 ImageField 字段类所创建的
            UserInfo.objects.create_user(avatar=file_obj, username='Kevin', password='123')  # 将文件对象传递给 avatar 字段
        else:
            UserInfo.objects.create_user(username='Kevin', password='123')  # 如果 file_obj 不是一个文件对象,那么不对 avatar 字段做任何操作,让 avatar 字段使用默认值
    return render(request, 'register.html')

5. .check_password('密码') -> 检测密码是否正确

  • 返回值: True/False

  • 检查查询到的用户密码是否正确

from django.contrib.auth.models import User

def my_view(request):
    user = User.objects.get(username='Yeung')

    isOk = user.check_password('123')  # 检查查询到的用户密码是否正确

    print(isOk)  # True
    return HttpResponse('添加成功')

  • 检查当前登录用户的密码是否正确

from django.contrib.auth.models import User

def my_view(request):

    isOk = request.user.check_password(raw_password='123')  # 检查当前登录用户密码是否正确

    print(isOk)  # True
    return HttpResponse('添加成功')

6. .set_password('密码') -> 修改用户密码

  • 注意: 设置完一定要调用用户对象的save方法!!!

  • 对查询到的用户密码进行修改

from django.contrib.auth.models import User

def my_view(request):
    user = User.objects.get(username='Yeung')

    user.set_password('456')  # 对查询到的用户密码进行修改
user.save()  # 一定要进行保存

    return HttpResponse('修改成功')

  • 对当前登录用户的密码进行修改

from django.contrib.auth.models import User

def my_view(request):

    request.user.set_password('1234')  # 对当前登录用户的密码进行修改
    request.user.save()  # 一定要进行保存

    return HttpResponse('修改成功')

  • 修改密码功能的简单演示

# 修改密码功能的简单演示

@login_required
def set_password(request):
    user = request.user
    err_msg = ''
    if request.method == 'POST':
        old_password = request.POST.get('old_password', '')
        new_password = request.POST.get('new_password', '')
        repeat_password = request.POST.get('repeat_password', '')
 # 检查旧密码是否正确
        if user.check_password(old_password):
            if not new_password:
                err_msg = '新密码不能为空'
            elif new_password != repeat_password:
                err_msg = '两次密码不一致'
            else:
                user.set_password(new_password)
                user.save()
                return redirect("/login/")
        else:
            err_msg = '原密码输入错误'
    content = {
        'err_msg': err_msg,
    }
    return render(request, 'set_password.html', content)

扩展默认auth_user表的字段


  • 通过继承Django内置的AbstractUser类(User类也是继承了AbstractUser类),从而实现扩展默认auth_user表的字段

  • 导入AbstractUser类

from django.contrib.auth.models import AbstractUser

  • 定义一个表的类,继承于AbstractUser类

# models.py

from django.db import models
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
'''
    新的用户表
    '''
    phone = models.CharField(max_length=11)
    address = models.CharField(max_length=15)

    def __str__(self):
        return self.username

  • 注意: 按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证

# settings.py

# AUTH_USER_MODEL = "app名.UserInfo"

AUTH_USER_MODEL = "app01.UserInfo"

  • 自定义认证系统默认使用的数据表之后,我们就可以像使用默认的auth_user表那样使用我们的UserInfo表了

    • 创建普通用户

# views.py

from .models import *

UserInfo.objects.create_user(username='用户名', password='密码')

    • 创建超级用户

# views.py

from .models import *

UserInfo.objects.create_superuser(username='用户名', password='密码')

  • 再次注意: 一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了